﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BReusable.T4
{
    public interface IValidationDictionary
    {
        void AddError(string key, string errorMessage);
        bool IsValid { get; }
    }
    internal static class CopyDictionary<T,TU> where T:TU
    {
        public static T CopyData(Func<T,TU,bool,Dictionary<string,Action>> actionDictionaryFunc,
            Func<T> creator, TU source, bool includeIdentifier, ICollection<string>excludeList)
        {
            return CopyDataMaster(actionDictionaryFunc, creator, source, includeIdentifier, excludeList,
                                  kvp => kvp.Value());
        }

        public static T CopyData(Func<T,TU,bool, Dictionary<string,Action>> actionDictionaryFunc,
            IValidationDictionary validation,Func<T> creator,TU source, bool includeIdentifier, ICollection<string> excludeList)
        {
            var result = CopyDataMaster(actionDictionaryFunc, creator, source, includeIdentifier, excludeList,
                                        kvp =>
                                            {
                                                try
                                                {
                                                    kvp.Value();
                                                }
                                                catch (Exception exception)
                                                {

                                                    validation.AddError(kvp.Key, exception.Message);

                                                }
                                            });
            if (validation.IsValid == false)
                throw new ArgumentException("Validation contains errors");
            return result;
        }

        private static T CopyDataMaster(Func<T,TU,bool,Dictionary<string,Action>> actionDictionaryFunc,
            Func<T> creator, TU source, bool includeIdentifier, ICollection<string> excludeList,
            Action<KeyValuePair<string,Action>>action)
        {
            var result = creator();
            foreach(var kvp in actionDictionaryFunc(result,source,includeIdentifier))
            {
                if (excludeList == null || excludeList.Contains(kvp.Key) == false)
                    action(kvp);
            }
            return result;
        }
    }
}
